#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import sys
import time

from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtGui import QIntValidator, QBrush, QColor
from PyQt5.QtWidgets import (QApplication, QWidget, QTableWidget, QTableWidgetItem,
                             QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QLineEdit,
                             QFileDialog, QMessageBox, QDialog, QDialogButtonBox, QCheckBox)
import vault as c
import alibaba_spider
from functools import partial
from concurrent.futures import ThreadPoolExecutor, as_completed


class AliCollectorUI(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.executor = None  # 添加线程池实例
        self.futures = []  # 存储所有future对象
        self.stop_flag = False  # 停止标志

    def initUI(self):
        # 表格
        self.tableWidget = QTableWidget()
        self.tableWidget.setColumnCount(8)
        # 设置表头样式
        header_style = """
          QHeaderView::section {
              background-color: #2c3e50;
              color: white;
              font-weight: bold;
              padding: 5px;
              border: 1px solid #34495e;
          }
          """
        self.tableWidget.horizontalHeader().setStyleSheet(header_style)
        self.tableWidget.setHorizontalHeaderLabels(
            ["店铺公司", "店铺链接", "产品链接", "产品标题", "产品类目", "产品价格", "最低起订量",
             "店铺等级"])

        # 设置表格双击事件
        self.tableWidget.cellDoubleClicked.connect(self.open_url_from_cell)
        data = []
        # 添加页数输入框
        self.page_label = QLabel("爬取页数:")
        self.page_input = QLineEdit()
        self.page_input.setFixedWidth(120)  # 设置固定宽度为120像素
        self.page_input.setPlaceholderText("请输入1-100的数字")
        self.page_input.setValidator(QIntValidator(1, 100))  # 限制只能输入1-100的数字
        self.page_input.textChanged.connect(self.validate_page_input)

        # 设置表格行数
        self.tableWidget.setRowCount(len(data))

        # 填充数据到表格 - 确保每个单元格数据都是字符串
        for row, row_data in enumerate(data):
            for col, cell_data in enumerate(row_data):
                item = QTableWidgetItem(str(cell_data))  # 确保转换为字符串
                self.tableWidget.setItem(row, col, item)

        # 条件设置区域
        self.set_condition_label = QLabel("设置搜索条件")
        self.set_condition_label.setStyleSheet("color: red; font-size: 20px; font-family: 'Microsoft YaHei';")

        # 根据商品名搜索
        self.product_name_checkbox = QCheckBox("根据商品名搜索")
        self.product_name_checkbox.setChecked(True)
        self.product_name_input = QLineEdit()

        # 采集控制区域
        self.start_collect_button = QPushButton("开始采集")
        self.stop_collect_button = QPushButton("停止采集")
        self.success_count_label = QLabel("成功采集条数： 0")

        # 设置按钮样式
        button_style = "background-color: orange; border-radius: 10px; padding: 5px;"
        self.start_collect_button.setStyleSheet(button_style)
        self.stop_collect_button.setStyleSheet(button_style)

        collect_layout = QHBoxLayout()
        collect_layout.addWidget(self.start_collect_button)
        collect_layout.addWidget(self.stop_collect_button)
        collect_layout.addWidget(self.success_count_label)

        # 数据操作区域
        self.export_button = QPushButton("导出数据")
        self.clear_button = QPushButton("清空数据")

        data_op_layout = QHBoxLayout()
        data_op_layout.addWidget(self.export_button)
        data_op_layout.addWidget(self.clear_button)

        # 搜索条件布局
        search_condition_layout = QHBoxLayout()
        search_condition_layout.addWidget(self.set_condition_label)
        search_condition_layout.addWidget(self.product_name_checkbox)
        search_condition_layout.addWidget(self.product_name_input)
        search_condition_layout.addWidget(self.page_label)
        search_condition_layout.addWidget(self.page_input)

        # 主布局
        main_layout = QVBoxLayout()
        main_layout.addWidget(self.tableWidget)
        main_layout.addLayout(search_condition_layout)
        main_layout.addLayout(collect_layout)
        main_layout.addLayout(data_op_layout)

        self.setLayout(main_layout)
        self.setWindowTitle("崽哥阿里巴巴国际站采集器")
        self.setGeometry(300, 300, 800, 600)

        self.start_collect_button.clicked.connect(self.start_collect)
        self.stop_collect_button.clicked.connect(self.stop_collect)
        self.export_button.clicked.connect(self.print_export)
        self.clear_button.clicked.connect(self.clear_data)

    def validate_page_input(self):
        """验证页数输入"""
        text = self.page_input.text()
        if text and not text.isdigit():
            self.page_input.setStyleSheet("color: red;")
            print(f"错误: 请输入数字，当前输入: {text}")
        else:
            self.page_input.setStyleSheet("")
            if text:  # 只有输入有效数字时才打印
                print(f"设置的爬取页数: {text}")

    def start_collect(self):
        # 获取商品名搜索框内容
        product_name = self.product_name_input.text()
        page_count = self.page_input.text() or "1"  # 默认1页
        data = {
            "product_keywords": str(product_name).strip(),
            "page": int(page_count)  # 添加页数参数
        }
        c.write_public_json(c.ENCRYPT_FILE, data, c.key)
        print(f"开始采集商品名称: {product_name}，页数: {page_count}")
        # 重新加载配置文件
        c.reload_config()
        time.sleep(0.1)  # 确保文件写入完成

        # 重置停止标志
        self.stop_flag = False

        # 创建线程池执行爬虫
        self.executor = ThreadPoolExecutor(max_workers=5)
        future = self.executor.submit(self.run_spider)
        future.add_done_callback(partial(self.on_spider_complete))
        self.futures.append(future)

    def run_spider(self):
        """执行爬虫并更新UI"""
        if self.stop_flag:
            return None

        try:
            spider_data = alibaba_spider.main()
            if not self.stop_flag:
                self.update_table(spider_data)
            return spider_data
        except Exception as e:
            if not self.stop_flag:
                print(f"爬虫执行出错: {e}")
            return None

    def on_spider_complete(self, future):
        """爬虫完成后的回调函数"""
        try:
            spider_data = future.result()
            self.update_table(spider_data)
        except Exception as e:
            print(f"爬虫执行出错: {e}")

    def update_table(self, data_list):
        """更新表格数据"""
        self.tableWidget.setRowCount(len(data_list))
        for row, row_data in enumerate(data_list):
            for col, cell_data in enumerate(row_data):
                item = QTableWidgetItem(str(cell_data))  # 确保转换为字符串

                # 检查是否是URL列（店铺链接和产品链接）
                if col in [1, 2] and (str(cell_data).startswith('http://') or str(cell_data).startswith('https://')):
                    item.setFlags(item.flags() | Qt.ItemIsEnabled)  # 保持可点击状态
                    item.setForeground(QBrush(QColor(0, 0, 255)))  # 设置为蓝色
                    item.setToolTip("双击打开链接 " + str(cell_data))  # 设置提示文本
                self.tableWidget.setItem(row, col, item)
        self.success_count_label.setText(f"成功采集条数： {len(data_list)}")

    def open_url_from_cell(self, row, column):
        """处理表格单元格双击事件，打开URL链接"""
        # 店铺链接是第2列(索引为2)，产品链接是第3列(索引为3)
        if column in (1, 2):  # 检查是否是店铺链接或产品链接列
            item = self.tableWidget.item(row, column)
            if item and item.text():
                url = item.text()
                if not url.startswith(('http://', 'https://')):
                    url = 'https://' + url  # 添加协议前缀
                QDesktopServices.openUrl(QUrl(url))  # 使用系统默认浏览器打开

    def stop_collect(self):
        """停止所有正在运行的采集线程"""
        print("正在停止采集...")
        self.stop_flag = True

        # 取消所有未完成的future
        for future in self.futures:
            if not future.done():
                future.cancel()

        # 关闭线程池
        if self.executor:
            self.executor.shutdown(wait=False)
            self.executor = None

        self.futures = []
        print("采集已停止")

    def print_collect_phone(self):
        print("采集电话功能被触发")

    def print_export(self):
        print("导出数据功能被触发")

    def clear_data(self):
        """清空表格数据"""
        self.tableWidget.setRowCount(0)  # 设置行数为0来清空表格
        self.success_count_label.setText("成功采集条数： 0")  # 重置计数器
        print("表格数据已清空")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ui = AliCollectorUI()
    ui.show()
    sys.exit(app.exec_())
